package com.corechina.apex_osswords.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corechina.apex_osswords.common.APEXOSSWordsException;
import com.corechina.apex_osswords.common.ImageUtils;
import com.corechina.apex_osswords.common.Response;
import com.corechina.apex_osswords.domain.dao.CoreFilesMapper;
import com.corechina.apex_osswords.domain.entity.CoreFiles;
import com.corechina.apex_osswords.domain.vo.FileVo;
import com.corechina.apex_osswords.domain.vo.ImageStaticVo;
import com.corechina.apex_osswords.domain.vo.ImageUrlVo;
import com.corechina.apex_osswords.domain.vo.ImageVo;
import com.corechina.apex_osswords.service.ICoreFilesService;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 文件表 服务实现类
 * </p>
 *
 * @author cc
 * @since 2022-03-11
 */
@Service
public class CoreFilesServiceImpl extends ServiceImpl<CoreFilesMapper, CoreFiles> implements ICoreFilesService {

    @Value("${uploadFilePath}")
    private String uploadFilePath;

    @Value("${staticImagePath}")
    private String staticImagePath;

    @Value("${staticImageUrl}")
    private String staticImageUrl;

    @Autowired
    private CoreFilesMapper coreFilesMapper;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    public Response uploadImage(MultipartFile file, String guidKey) {
        if (file == null) {
            return Response.error("未接收到文件");
        }
        CoreFiles coreFiles = new CoreFiles();
        String realName = file.getOriginalFilename();
        String ext = realName.substring(realName.lastIndexOf("."));
        //判断上传文件中是否存在非法格式文件
        if (!ext.toLowerCase().equals(".webp") && !ext.toLowerCase().equals(".png") && !ext.toLowerCase().equals(".jpg") && !ext.toLowerCase().equals(".jpeg") && !ext.toLowerCase().equals(".bmp")) {
            return Response.error("文件格式不正确");
        }
        String fileName = UUID.randomUUID().toString() + ext;
        String thumbnailName = UUID.randomUUID().toString() + "-thumbnail" + ext;
        coreFiles.setGuidKey(guidKey);
        coreFiles.setExt(ext);
        coreFiles.setRealName(realName);
        coreFiles.setFileName(fileName);
        coreFiles.setThumbnailPath(thumbnailName);
        coreFiles.setPath(sdf.format(new Date()) + "/" + fileName);
        coreFiles.setThumbnailPath(sdf.format(new Date()) + "/" + thumbnailName);
        coreFiles.setLength(String.valueOf(file.getSize()));

        File dest = new File(new File(uploadFilePath).getAbsolutePath() + "/" + coreFiles.getPath());
        if (!dest.getParentFile().exists()) {
            try {
                dest.getParentFile().mkdirs();
            } catch (Exception e) {
                return Response.error("目录创建失败");
            }
        }

        FileVo fileVo = new FileVo();
        fileVo.setFileName(coreFiles.getRealName());
        try {
            file.transferTo(dest);
            Thumbnails.of(uploadFilePath + "/" + coreFiles.getPath())
                    .forceSize(100, 100)
                    .toFile(uploadFilePath + "/" + coreFiles.getThumbnailPath());
            coreFilesMapper.insert(coreFiles);
            fileVo.setId(coreFiles.getId());
        } catch (Exception e) {
            return Response.error("文件保存失败");
        }
        return Response.ok(fileVo);
    }

    @Override
    public Response uploadFile(MultipartFile file, String guidKey) {
        CoreFiles coreFiles = new CoreFiles();
        String realName = file.getOriginalFilename();
        String ext = realName.substring(realName.lastIndexOf("."));
        //判断上传文件中是否存在非法格式文件
        if (!ext.equals(".doc") && !ext.equals(".docx") && !ext.equals(".xls") && !ext.equals(".xlsx") && !ext.equals(".pdf") && !ext.equals(".txt") && !ext.equals(".png") && !ext.equals(".jpg") && !ext.equals(".jpeg") && !ext.equals(".gif") && !ext.equals(".csv")) {
            return Response.error("文件格式不正确");
        }
        String fileName = UUID.randomUUID().toString() + ext;
        String thumbnailName = UUID.randomUUID().toString() + "-thumbnail" + ext;
        coreFiles.setGuidKey(guidKey);
        coreFiles.setExt(ext);
        coreFiles.setRealName(realName);
        coreFiles.setFileName(fileName);
        coreFiles.setThumbnailPath(thumbnailName);
        coreFiles.setPath(sdf.format(new Date()) + "/" + fileName);
        coreFiles.setThumbnailPath(sdf.format(new Date()) + "/" + thumbnailName);
        coreFiles.setLength(String.valueOf(file.getSize()));

        File dest = new File(new File(uploadFilePath).getAbsolutePath() + "/" + coreFiles.getPath());
        if (!dest.getParentFile().exists()) {
            try {
                dest.getParentFile().mkdirs();
            } catch (Exception e) {
                return Response.error("目录创建失败");
            }
        }

        FileVo fileVo = new FileVo();
        fileVo.setFileName(coreFiles.getRealName());
        try {
            file.transferTo(dest);
            coreFilesMapper.insert(coreFiles);
            fileVo.setId(coreFiles.getId());
        } catch (Exception e) {
            return Response.error("文件保存失败");
        }

        return Response.ok(fileVo);
    }

    public void downloadFile(HttpServletResponse resp, Integer id) {
        try {
            CoreFiles dbfile = coreFilesMapper.selectById(id);
            if (dbfile == null) {
                throw new APEXOSSWordsException(404, "未找到要下载的文件");
            }

            File file = new File(uploadFilePath + "/" + dbfile.getPath());
            if (!file.exists()) {
                throw new APEXOSSWordsException(404, "未找到要下载的文件");
            }
            resp.setHeader("filename", URLEncoder.encode(dbfile.getRealName(), "utf-8"));
            resp.setHeader("Access-Control-Expose-Headers", "filename");
            resp.setHeader("content-type", "application/octet-stream");
            resp.setContentType("application/octet-stream");
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(dbfile.getRealName(), "utf-8"));
            byte[] buff = new byte[1024];
            BufferedInputStream bis = null;
            OutputStream os = null;
            try {
                os = resp.getOutputStream();
                bis = new BufferedInputStream(new FileInputStream(file));
                int i = bis.read(buff);
                while (i != -1) {
                    os.write(buff, 0, buff.length);
                    os.flush();
                    i = bis.read(buff);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            throw new APEXOSSWordsException(500, "下载失败");
        }
    }

    @Override
    public Response delFile(Integer id) {
        coreFilesMapper.updateIsDel(1, id);
//        CoreFiles coreFiles = coreFilesMapper.selectById(id);
//        if (coreFiles != null) {
//            File dest = new File(uploadFilePath + "/" + coreFiles.getPath());
//            if (dest.exists() && coreFilesMapper.deleteById(id) > 0 && dest.delete()) {
//                if (coreFiles.getThumbnailPath() != null) {
//                    File dest2 = new File(uploadFilePath + "/" + coreFiles.getThumbnailPath());
//                    if (dest2.exists() && dest2.delete()) {
//                        return Response.ok();
//                    }
//                    return Response.error("缩略图删除失败");
//
//                }
//            }
//        }
        return Response.ok();
    }

    @Override
    public Response getImageListByGuidKey(String guidKey, Integer type) {
        List<ImageVo> imageVoList = new ArrayList<>();
        QueryWrapper<CoreFiles> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("guid_key", guidKey).orderByAsc("id").eq("is_del", 0);
        List<CoreFiles> coreFilesList = coreFilesMapper.selectList(queryWrapper);
        if (type == 0) {
            for (CoreFiles coreFiles : coreFilesList) {
                ImageVo imageVo = new ImageVo();
                if (coreFiles.getThumbnailPath() != null) {
                    imageVo.setId(coreFiles.getId());
                    imageVo.setImageBase64(ImageUtils.takeImageToBASE64(uploadFilePath, coreFiles.getThumbnailPath()));
                    imageVoList.add(imageVo);
                }
            }
        } else if (type == 1) {
            for (CoreFiles coreFiles : coreFilesList) {
                ImageVo imageVo = new ImageVo();
                if (coreFiles.getPath() != null) {
                    imageVo.setId(coreFiles.getId());
                    imageVo.setImageBase64(ImageUtils.takeImageToBASE64(uploadFilePath, coreFiles.getPath()));
                    imageVoList.add(imageVo);
                }
            }
        }
        return Response.ok(imageVoList);
    }

    @Override
    public ImageVo getById(Integer id, Integer type) {
        ImageVo imageVo = new ImageVo();
        CoreFiles coreFiles = coreFilesMapper.selectById(id);
        if (type == 0) {
            imageVo.setId(coreFiles.getId());
            imageVo.setImageBase64(ImageUtils.takeImageToBASE64(uploadFilePath, coreFiles.getThumbnailPath()));
        } else if (type == 1) {
            imageVo.setId(coreFiles.getId());
            imageVo.setImageBase64(ImageUtils.takeImageToBASE64(uploadFilePath, coreFiles.getPath()));
        }
        return imageVo;
    }

    @Override
    public ImageVo getByGuidKey(String guidKey) {
        QueryWrapper<CoreFiles> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("guid_key", guidKey);
        queryWrapper.eq("is_del", 0);
        ImageVo imageVo = new ImageVo();
        CoreFiles coreFiles = coreFilesMapper.selectOne(queryWrapper);
        if (coreFiles == null) {
            return imageVo;
        }
        imageVo.setId(coreFiles.getId());
        imageVo.setImageBase64(ImageUtils.takeImageToBASE64(uploadFilePath, coreFiles.getPath()));
        return imageVo;
    }

    @Override
    public ImageStaticVo uploadImageForStatic(MultipartFile file) {
        ImageStaticVo imageStaticVo = new ImageStaticVo();
        ImageUrlVo imageUrlVo = new ImageUrlVo();
        if (file == null) {
            imageStaticVo.setErrno(1);
//            return Response.error("未接收到文件");
        }
        CoreFiles coreFiles = new CoreFiles();
        String realName = file.getOriginalFilename();
        String ext = realName.substring(realName.lastIndexOf("."));
        //判断上传文件中是否存在非法格式文件
        if (!ext.toLowerCase().equals(".webp") && !ext.toLowerCase().equals(".png") && !ext.toLowerCase().equals(".jpg") && !ext.toLowerCase().equals(".jpeg") && !ext.toLowerCase().equals(".bmp")) {
            imageStaticVo.setErrno(1);
//            return Response.error("文件格式不正确");
        }
        String uuid = UUID.randomUUID().toString();
        String fileName = uuid + ext;
        String thumbnailName = uuid + "-thumbnail" + ext;
        coreFiles.setGuidKey(uuid);
        coreFiles.setExt(ext);
        coreFiles.setRealName(realName);
        coreFiles.setFileName(fileName);
        coreFiles.setThumbnailPath(thumbnailName);
        coreFiles.setPath(fileName);
        coreFiles.setThumbnailPath(thumbnailName);
        coreFiles.setLength(String.valueOf(file.getSize()));

        File dest = new File(new File(staticImagePath).getAbsolutePath() + "/" + coreFiles.getPath());
        if (!dest.getParentFile().exists()) {
            try {
                dest.getParentFile().mkdirs();
            } catch (Exception e) {
                imageStaticVo.setErrno(1);
//                return Response.error("目录创建失败");
            }
        }
        try {
            file.transferTo(dest);
            Thumbnails.of(staticImagePath + coreFiles.getPath())
                    .forceSize(100, 100)
                    .toFile(staticImagePath + coreFiles.getThumbnailPath());
            coreFilesMapper.insert(coreFiles);
        } catch (Exception e) {
            imageStaticVo.setErrno(1);
//            return Response.error("文件保存失败");
        }
        imageUrlVo.setUrl(staticImageUrl + coreFiles.getPath());
        imageUrlVo.setAlt(coreFiles.getRealName());
        imageStaticVo.setErrno(0);
        imageStaticVo.setData(imageUrlVo);
        return imageStaticVo;

    }

}
